//
// Created by 赵路 on 2021/10/12.
//

#include <iostream>
#include <fstream>
#include "des.h"

using namespace std;

int main() {
    string k;
    do {
        cout << "Please input your key (8 characters):" << endl;
        cin >> k;
    } while (k.length() != 8);
    Key = charToBitset(k.c_str());
    generateKeys();

    cout << "Choose the input method (1.command line input 2.file input):" << endl;
    int choice;
    cin >> choice;
    switch (choice) {
        case 1: {
            cout << "Please input the text you want to encrypt:" << endl;
            string s;
            cin >> s;
            if (s.length() % 8 != 0) {
                int x = ((int) s.length() / 8 + 1) * 8 - (int) s.length();
                // 填充
                s.append("1");
                for (int i = 1; i < x; ++i) {
                    s.append("0");
                }
            }

            ofstream out;
            out.open("cipher.txt", ios::binary);
            for (int i = 0; i < s.length(); i += 8) {
                string ss = s.substr(i, 8);
                bitset<64> plain = charToBitset(ss.c_str());
                bitset<64> cipher = encrypt(plain);
                out.write((char *) &cipher, sizeof(cipher));
                plain.reset();
            }
            out.close();

            ifstream in;
            in.open("cipher.txt", ios::binary);
            out.open("decrypted.txt", ios::binary);
            bitset<64> text;
            while (in.read((char *) &text, sizeof(text))) {
                bitset<64> temp = decrypt(text);
                out.write((char *) &temp, sizeof(temp));
                text.reset();
            }
            in.close();
            out.close();

            in.open("decrypted.txt", ios::binary);
            char ch;
            cout << "解密后的内容：";
            while (in.read((char *) &ch, sizeof(ch))) {
                if (ch == '1') {
                    break;
                }
                cout << ch;
            }
            in.close();
            cout << endl;
            break;
        }
        case 2: {
            ifstream in;
            ofstream out;

            in.open("plain.txt", ios::binary);
            out.open("cipher.txt", ios::binary);
            bitset<64> plain;
            while (in.read((char *) &plain, sizeof(plain))) {
                bitset<64> cipher = encrypt(plain);
                out.write((char *) &cipher, sizeof(cipher));
                plain.reset();
            }
            in.close();
            out.close();

            in.open("cipher.txt", ios::binary);
            out.open("decrypted.txt", ios::binary);
            while (in.read((char *) &plain, sizeof(plain))) {
                bitset<64> temp = decrypt(plain);
                out.write((char *) &temp, sizeof(temp));
                plain.reset();
            }
            in.close();
            out.close();
            break;
        }
        default: {
            break;
        }
    }
    return 0;
}
